home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1998 August / PC Plus SuperCD 50a Issue 142 (CD142a) (August 1998).iso / full / jbuild / setup / JBuilder / jsamples.z / Chessboard.java < prev    next >
Encoding:
Java Source  |  1997-07-15  |  32.4 KB  |  1,019 lines

  1. //
  2. // Chessboard.java
  3. //
  4.  
  5. package borland.samples.apps.chess.client.board;
  6.  
  7. import java.awt.event.*;
  8. import java.net.URL;
  9. import java.awt.*;
  10. import java.awt.image.*;
  11.  
  12. public class Chessboard extends Canvas implements MouseMotionListener, MouseListener, Runnable
  13. {
  14.   boolean animate = true;
  15.   boolean badTimeToStopThread = false;
  16.   boolean mouseActive = false;
  17.   boolean blackOnTop = true;
  18.   boolean blackGoesOnTop = false;
  19.   boolean retryImage = false;
  20.   boolean isLive ; //Chessboard enabled  state
  21.   boolean imageLoadError = false;
  22.   boolean init = false ;
  23.   boolean initfailed = false;
  24.   private Color darkSquareColor;
  25.   private Color lightSquareColor;
  26.   ActionListener listener;
  27.   Image iBoard;
  28.   Image iBackground;
  29.   Image promoteWhite;
  30.   Image promoteBlack;
  31.   Image iAnimationBackground;
  32.   Image iPiece[] ;
  33.   Image iPiecemask[];
  34.   FilteredImageSource masksource[];
  35.   int offset[] ;
  36.   int endrank;
  37.   int startrank;
  38.   int endfile;
  39.   int startfile;
  40.   Thread timer = null;
  41.   Boardsquares squareColor;
  42.   Boardsquares prevpos;
  43.   Boardsquares pieceColor;
  44.   Boardsquares updateArray;
  45.   public static final int LIGHTSQUARE = 0;
  46.   public static final int DARKSQUARE = 16;
  47.   public static final int BLACKPIECE = 8;
  48.   public static final int WHITEPIECE = 0;
  49.   public static final int PAWN   = 1;
  50.   public static final int KNIGHT = 2;
  51.   public static final int BISHOP = 3;
  52.   public static final int ROOK   = 4;
  53.   public static final int QUEEN  = 5;
  54.   public static final int KING   = 6;
  55.   static final String [] file = {"a","b","c","d","e","f","g","h"};
  56.   String initstring = "Loading Chessboard image...";
  57.   String message = "Initialization failed";
  58.   int xoffset;
  59.   int yoffset;
  60.   MediaTracker tracker;
  61.   int p;
  62.   int xincrement;
  63.   int yincrement;
  64.   int xOldMouse;
  65.   int yOldMouse;
  66.   int pointbx = 0;
  67.   int pointby = 0;
  68.   int finalPiece;
  69.   MoveTuple tuple;
  70.   Font boldfont;
  71.   long currentTime = 0;
  72.   private URL boardURL = null;
  73.   private String boardPath = "" ;
  74.  
  75.   public Chessboard ()  {
  76.     try {
  77.       addMouseMotionListener(this);
  78.       addMouseListener(this);
  79.       darkSquareColor = Color.blue;
  80.       lightSquareColor = Color.lightGray;
  81.       boldfont    = new Font("Dialog",Font.BOLD,10) ;
  82.       squareColor = new Boardsquares();
  83.       prevpos     = new Boardsquares();
  84.       pieceColor  = new Boardsquares();
  85.       updateArray = new Boardsquares();
  86.       int i;
  87.       int j;
  88.       offset = new int[8];
  89.       offset[1] = 35;
  90.       iPiece = new Image[32];
  91.       masksource = new FilteredImageSource[16]  ;
  92.       iPiecemask = new Image[16];
  93.       for(j=0;j<8;j=j+2) {
  94.         for(i=0;i<8;i=i+2) {
  95.             squareColor.assign(j+1,i+1,DARKSQUARE);
  96.           squareColor.assign(j+1,i,LIGHTSQUARE);
  97.           squareColor.assign(j,i,DARKSQUARE);
  98.           squareColor.assign(j,i+1,LIGHTSQUARE);
  99.         }
  100.       }
  101.       for(j=0;j<8;j++) {
  102.         prevpos.assign(j,1,PAWN);
  103.         prevpos.assign(j,6,PAWN);
  104.         for(i=0;i<2;i++)  {
  105.             pieceColor.assign(j,i,WHITEPIECE);
  106.           pieceColor.assign(j,i+6,BLACKPIECE);
  107.         }
  108.       }
  109.       prevpos.assign(0,0,ROOK);
  110.       prevpos.assign(1,0,KNIGHT);
  111.       prevpos.assign(2,0,BISHOP);
  112.       prevpos.assign(3,0,QUEEN);
  113.       prevpos.assign(4,0,KING);
  114.       prevpos.assign(5,0,BISHOP);
  115.       prevpos.assign(6,0,KNIGHT);
  116.       prevpos.assign(7,0,ROOK);
  117.       prevpos.assign(0,7,ROOK);
  118.       prevpos.assign(1,7,KNIGHT);
  119.       prevpos.assign(2,7,BISHOP);
  120.       prevpos.assign(3,7,QUEEN);
  121.       prevpos.assign(4,7,KING);
  122.       prevpos.assign(5,7,BISHOP);
  123.       prevpos.assign(6,7,KNIGHT);
  124.       prevpos.assign(7,7,ROOK);
  125.     }
  126.     catch (Exception e) {
  127.       message = e.toString()  ;
  128.       e.printStackTrace();
  129.       initfailed = true;
  130.     }
  131.   }
  132.  
  133.   public Boardsquares getPiecePosition() {
  134.     return prevpos;
  135.   }
  136.  
  137.   public Boardsquares getColorPosition() {
  138.     return pieceColor;
  139.   }
  140.  
  141.   // java.awt.Component method
  142.   public Dimension getPreferredSize() {
  143.     if (offset[1] > 12)   {
  144.       System.err.println("Board preferred Size =(" +  offset[1] + "*8)+12");
  145.       return new Dimension((offset[1] * 8) + 12, (offset[1] * 8) + 12);
  146.     }  
  147.     else
  148.       return new Dimension(292, 292);
  149.   }
  150.  
  151.   public void setImageName(String boardPath) {
  152.     this.boardPath = boardPath;
  153.     try {
  154.       setImageURL(new URL(boardPath));
  155.     }
  156.     catch (Exception e) {
  157.       System.err.println("setImagePath " + e);
  158.     }
  159.   }
  160.  
  161.   public String getImageName() {
  162.     return boardPath;
  163.   }
  164.  
  165.   public void setImageURL(URL boardURL) {
  166.     this.boardURL = boardURL;
  167.     setImage(getToolkit().getImage(boardURL));
  168.   }
  169.  
  170.   public URL getImageURL() {
  171.     return boardURL;
  172.   }
  173.  
  174.   public synchronized void  setImage(Image iPieces){
  175.     try{
  176.       if (iPieces == null)  {
  177.         System.err.println("setImage - image is null");
  178.         return;
  179.       }
  180.       init = false;
  181.       retryImage = false;
  182.       System.err.println("Chessboard.setImage...");
  183.       tracker = new MediaTracker(this);
  184.       tracker.addImage(iPieces,0);
  185.       tracker.waitForAll();
  186.       //System.out.println("done waiting for image...");
  187.       offset[0] = 0;
  188.       offset[1] = iPieces.getWidth(this) / 6;
  189.       //System.out.println("Square width=" + offset[1]);
  190.       if (offset[1] < 10) {
  191.         System.out.println("This image is too small.");
  192.         retryImage = true;
  193.         return;
  194.       }
  195.       int i;
  196.       for (i=2;i < 8;i++)  {
  197.         offset[i] = offset[1] * i;
  198.       }
  199.       initstring = CVS.LOADING_PIECES_;
  200.  
  201.       ImageFilter tfilter = new Transparent();
  202.       MediaTracker trackr ;
  203.       trackr  = new MediaTracker(this);
  204.       FilteredImageSource  mask = new FilteredImageSource(iPieces.getSource(),
  205.                                                     tfilter);
  206.       iPieces = createImage(mask);
  207.       trackr.addImage(iPieces,0);
  208.  
  209.       try {
  210.         initstring = CVS.LOADING_BLACK_PIECE;
  211.         trackr.waitForID(0);
  212.         initstring = CVS.LOADING_WHITE_PIECE;
  213.         //System.out.println("waitForAll did not crash...  " );
  214.       }
  215.       catch (Exception e){
  216.         System.out.println("waitForAll failed ");
  217.        e.printStackTrace();
  218.       }
  219.  
  220.       for (i=0;i<32;i++) {
  221.         iPiece[i] = createImage(offset[1],offset[1]);
  222.       }
  223.        for (i=0;i<16;i++) {
  224.         iPiecemask[i] = createImage(offset[1],offset[1]);
  225.       }
  226.       //System.out.println("create maskimages ");
  227.       Graphics gPiece;
  228.       //pieces
  229.       //pawns
  230.       CropImageFilter crop = new CropImageFilter(offset[5],offset[0],offset[1],offset[1]);
  231.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  232.       iPiecemask[PAWN+WHITEPIECE] = createImage(mask);
  233.       trackr.addImage(iPiecemask[PAWN+WHITEPIECE],1);
  234.       crop = new CropImageFilter(offset[5],offset[1],offset[1],offset[1]);
  235.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  236.       iPiecemask[PAWN+BLACKPIECE] = createImage(mask);
  237.       trackr.addImage(iPiecemask[PAWN+BLACKPIECE],1);
  238.       //knights
  239.       crop = new CropImageFilter(offset[1],offset[0],offset[1],offset[1]);
  240.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  241.       iPiecemask[KNIGHT+WHITEPIECE] = createImage(mask);
  242.       trackr.addImage(iPiecemask[KNIGHT+WHITEPIECE],1);
  243.       crop = new CropImageFilter(offset[1],offset[1],offset[1],offset[1]);
  244.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  245.       iPiecemask[KNIGHT+BLACKPIECE] = createImage(mask);
  246.       trackr.addImage(iPiecemask[KNIGHT+BLACKPIECE],1);
  247.       //bishops
  248.       crop = new CropImageFilter(offset[2],offset[0],offset[1],offset[1]);
  249.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  250.       iPiecemask[BISHOP+WHITEPIECE] = createImage(mask);
  251.       trackr.addImage(iPiecemask[BISHOP+WHITEPIECE],1);
  252.       crop = new CropImageFilter(offset[2],offset[1],offset[1],offset[1]);
  253.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  254.       iPiecemask[BISHOP+BLACKPIECE] = createImage(mask);
  255.       trackr.addImage(iPiecemask[BISHOP+BLACKPIECE],1);
  256.       //rooks
  257.       crop = new CropImageFilter(offset[0],offset[0],offset[1],offset[1]);
  258.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  259.       iPiecemask[ROOK+WHITEPIECE] = createImage(mask);
  260.       trackr.addImage(iPiecemask[ROOK+WHITEPIECE],1);
  261.       crop = new CropImageFilter(offset[0],offset[1],offset[1],offset[1]);
  262.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  263.       iPiecemask[ROOK+BLACKPIECE] = createImage(mask);
  264.       trackr.addImage(iPiecemask[ROOK+BLACKPIECE],1);
  265.       //queens
  266.       crop = new CropImageFilter(offset[3],offset[0],offset[1],offset[1]);
  267.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  268.       iPiecemask[QUEEN+WHITEPIECE] = createImage(mask);
  269.       trackr.addImage(iPiecemask[QUEEN+WHITEPIECE],1);
  270.       crop = new CropImageFilter(offset[3],offset[1],offset[1],offset[1]);
  271.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  272.       iPiecemask[QUEEN+BLACKPIECE] = createImage(mask);
  273.       trackr.addImage(iPiecemask[QUEEN+BLACKPIECE],1);
  274.       //kings
  275.       crop = new CropImageFilter(offset[4],offset[0],offset[1],offset[1]);
  276.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  277.       iPiecemask[KING+LIGHTSQUARE+WHITEPIECE] = createImage(mask);
  278.       trackr.addImage(iPiecemask[KING+WHITEPIECE],1);
  279.  
  280.       crop = new CropImageFilter(offset[4],offset[1],offset[1],offset[1]);
  281.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  282.       iPiecemask[KING+LIGHTSQUARE+BLACKPIECE] = createImage(mask);
  283.       trackr.addImage(iPiecemask[KING+BLACKPIECE],1);
  284.  
  285.       int ImageWidth  = offset[1]*8;
  286.       int ImageHeight = ImageWidth;
  287.       iBoard = createImage(ImageWidth + 12,ImageWidth + 12);
  288.       iBackground = createImage(offset[1],offset[1]);
  289.       iAnimationBackground = createImage(offset[1],offset[1]);
  290.       initstring = CVS.LOADING_MASKS_;
  291.       try {
  292.         initstring = CVS.LOADING_BLACK_PIECE;
  293.         trackr.waitForID(1);
  294.         initstring = CVS.LOADING_WHITE_PIECE;
  295.         //System.out.println("waitForAll did not crash  " );
  296.       }
  297.       catch (Exception e){
  298.         System.out.println("waitForAll failed ");
  299.        e.printStackTrace();
  300.       }
  301.       repaint();
  302.       setLightSquareColor(lightSquareColor);
  303.       setDarkSquareColor(darkSquareColor);
  304.       promoteBlack = createImage(offset[1]*4,offset[1]);
  305.       promoteWhite = createImage(offset[1]*4,offset[1]);
  306.       if (promoteBlack == null)  {
  307.         retryImage = true;
  308.         System.err.println("Chessboard.SetImage promoteBlack=null " + offset[1]);
  309.         return;
  310.       }
  311.       System.err.println("Chessboard.SetImage build initial position");
  312.       Graphics   g = promoteBlack.getGraphics();
  313.       g.drawImage(iPiece[ROOK+LIGHTSQUARE+BLACKPIECE],0,0,this);
  314.       g.translate(offset[1],0);
  315.       g.drawImage(iPiece[KNIGHT+DARKSQUARE+BLACKPIECE],0,0,this);
  316.       g.translate(offset[1],0);
  317.       g.drawImage(iPiece[BISHOP+LIGHTSQUARE+BLACKPIECE],0,0,this);
  318.       g.translate(offset[1],0);
  319.       g.drawImage(iPiece[QUEEN+DARKSQUARE+BLACKPIECE],0,0,this);
  320.       g.dispose();
  321.       g = promoteWhite.getGraphics();
  322.       g.drawImage(iPiece[ROOK+DARKSQUARE+WHITEPIECE],0,0,this);
  323.       g.translate(offset[1],0);
  324.       g.drawImage(iPiece[KNIGHT+LIGHTSQUARE+WHITEPIECE],0,0,this);
  325.       g.translate(offset[1],0);
  326.       g.drawImage(iPiece[BISHOP+DARKSQUARE+WHITEPIECE],0,0,this);
  327.       g.translate(offset[1],0);
  328.       g.drawImage(iPiece[QUEEN+LIGHTSQUARE+WHITEPIECE],0,0,this);
  329.       g.dispose();
  330.  
  331.       setSize(getPreferredSize());
  332.       init = true;
  333.       setPosition(prevpos,pieceColor);
  334.       drawBorder();
  335.       //System.err.println("Chessboard.SetImage last repaint");
  336.       initstring = CVS.CREATING_INITIAL;
  337.       repaint();
  338.       //System.err.println("Chessboard.SetImage return from repaint");
  339.     }
  340.     catch (Exception e) {
  341.       e.printStackTrace();
  342.       System.err.println("Chessboard.init " + e.toString());
  343.       repaint(0);
  344.     }
  345.     //System.err.println("Chessboard.init end");
  346.   }
  347.  
  348.   public void setLightSquareColor(Color color) {
  349.     lightSquareColor = color;
  350.     if (iBoard != null) {
  351.       Graphics square = iPiece[0].getGraphics();
  352.       fillSquare(square,lightSquareColor);
  353.       square.dispose();
  354.       square = iPiece[8].getGraphics();
  355.       fillSquare(square,lightSquareColor);
  356.       square.dispose();
  357.       for (int i=1; i< 7;i++) {
  358.         for (int j=0; j <= BLACKPIECE;j=j+BLACKPIECE) {
  359.           // System.out.println("draw piece " + i + ","+ j);
  360.           Graphics g = iPiece[i+j+LIGHTSQUARE].getGraphics();
  361.           g.drawImage(iPiece[LIGHTSQUARE],0,0,this);
  362.           g.drawImage(iPiecemask[i+j],0,0,this);
  363.           g.dispose();
  364.         }
  365.       }
  366.       if (init)
  367.         repaint();
  368.     }
  369.   }
  370.  
  371.   public Color getLightSquareColor() {
  372.     return lightSquareColor;
  373.   }
  374.  
  375.   private void fillSquare(Graphics square,Color color) {
  376.      square.setColor(color);
  377.      square.fillRect(0,0,offset[1],offset[1]);
  378.   }
  379.  
  380.   public void setDarkSquareColor(Color color) {
  381.     darkSquareColor = color;
  382.     if (iBoard != null) {
  383.       Graphics square = iPiece[16].getGraphics();
  384.       fillSquare(square,darkSquareColor);
  385.       square.dispose();
  386.       square = iPiece[24].getGraphics();
  387.       fillSquare(square,darkSquareColor);
  388.       square.dispose();
  389.       for (int i=1; i< 7;i++) {
  390.         for (int j=0; j <= BLACKPIECE;j=j+BLACKPIECE) {
  391.           // System.out.println("draw piece " + i + ","+ j);
  392.           Graphics g = iPiece[i+j+DARKSQUARE].getGraphics();
  393.           g.drawImage(iPiece[16],0,0,this);
  394.           g.drawImage(iPiecemask[i+j],0,0,this);
  395.           g.dispose();
  396.         }
  397.       }
  398.       if (init)
  399.         repaint();
  400.     }
  401.   }
  402.  
  403.   public Color getDarkSquareColor() {
  404.     return darkSquareColor;
  405.   }
  406.  
  407.   void drawBorder() {
  408.     if (iBoard == null)
  409.       return;
  410.     Graphics gBoard = iBoard.getGraphics();
  411.     if (gBoard == null)
  412.       return;
  413.     blackGoesOnTop = blackOnTop;
  414.     gBoard.setColor(getBackground());
  415.     int imagewidth = offset[1] * 8;
  416.     gBoard.fillRect(imagewidth,0,12,imagewidth + 12);
  417.     gBoard.fillRect(0,imagewidth,imagewidth,12);
  418.     gBoard.setColor(Color.black );
  419.     gBoard.setFont(boldfont);
  420.     int xoffset = (offset[1] -  8) / 2;
  421.     int yoffset = (offset[1] + 12) / 2;
  422.     if (blackOnTop) {
  423.       for (int i=0;i<8;i++)  {
  424.         gBoard.drawString(String.valueOf(8-i),imagewidth + 2,(i * offset[1]) + yoffset);
  425.       }
  426.       for (int i=0;i<8;i++) {
  427.         gBoard.drawString(file[i],(i * offset[1]) + xoffset,imagewidth + 10);
  428.       }
  429.     }
  430.     else {
  431.       for (int i=0;i<8;i++) {
  432.         gBoard.drawString(String.valueOf(1+i),imagewidth + 2,(i * offset[1]) + yoffset);
  433.       }
  434.       for (int i=0;i<8;i++) {
  435.         gBoard.drawString(file[7-i],(i * offset[1]) + xoffset,imagewidth + 10);
  436.       }
  437.     }
  438.     gBoard.dispose();
  439.   }
  440.  
  441.   public void setPosition(){
  442.     setPosition(prevpos,pieceColor);
  443.   }
  444.  
  445.   public void setPosition(Boardsquares piecearray,Boardsquares colorarray)  {
  446.     if (init) {
  447.     int rank = 0;
  448.     int file = 0;
  449.     int xoff = offset[1];
  450.     int yoff = offset[1];
  451.     int i = 0;
  452.     int newxoff;
  453.     int newyoff;
  454.     int squarecount = 0;
  455.     int pointax=0;
  456.     int pointay = 0;
  457.     xincrement = 0;
  458.     yincrement =0;
  459.     updateArray.init(prevpos);
  460.     updateArray.add(pieceColor);
  461.     updateArray.subtract(piecearray);
  462.     updateArray.subtract(colorarray);
  463.     for (rank = 0 ; rank < 8 ; rank++) {
  464.       for (file = 0 ; file < 8 ; file++) {
  465.         if (updateArray.value(file,rank) != 0) {
  466.           if (squarecount < 2) {
  467.             if (squarecount == 0) {
  468.               pointax = file;
  469.               pointay = rank;
  470.             }
  471.             else {
  472.               pointbx = file;
  473.               pointby = rank;
  474.             }
  475.           }
  476.           squarecount++;
  477.         }
  478.       }
  479.     }
  480.     boolean doAnimation  = false;
  481.     if (squarecount == 2 && timer == null) {
  482.       if (piecearray.value(pointax,pointay) > 0 &&
  483.           prevpos.value(pointbx,pointby) > 0 ) {
  484.         file = pointax;
  485.         rank = pointay;
  486.         pointay = pointby;
  487.         pointax = pointbx;
  488.         pointbx = file;
  489.         pointby = rank;
  490.       }
  491.       file = pointax;
  492.       rank = pointay;
  493.       if (blackOnTop) {
  494.            xincrement = 2 *(pointbx - pointax); //left is 0, right is 7
  495.            yincrement = 2 *(pointay - pointby); //top is 7 bottom is 0
  496.         newxoff = file*xoff;
  497.         newyoff =  yoff*7 - (rank*yoff);
  498.       }
  499.       else  {
  500.            xincrement = 2 *(pointax - pointbx); //left is 7, right is 0
  501.            yincrement = 2 *(pointby - pointay); //top is 0 bottom is 7
  502.         newxoff = xoff*7 -(file*xoff);
  503.            newyoff = rank*yoff;
  504.       }
  505.       //set initial background to new square contents
  506.       synchronized (this) {
  507.         p = squareColor.value(file,rank) +
  508.             piecearray.value(file,rank) +
  509.             colorarray.value(file,rank);
  510.         Graphics gAnimationBackground = iAnimationBackground.getGraphics();
  511.         gAnimationBackground.drawImage(iPiece[p],0,0,this);
  512.         gAnimationBackground.dispose();
  513.         p = pieceColor.value(file,rank) +
  514.             prevpos.value(file,rank);
  515.         finalPiece = piecearray.value(pointbx,pointby) +
  516.                      colorarray.value(pointbx,pointby) ;
  517.          xoffset = newxoff;
  518.         yoffset = newyoff;
  519.         if (colorarray.value(pointbx,pointby) == pieceColor.value(file,rank) && piecearray.value(pointbx,pointby) > 0) {
  520.           timer = new Thread(this);
  521.           timer.start();
  522.           doAnimation = true;
  523.         }
  524.       }
  525.     }
  526.     if (!doAnimation) {
  527.       synchronized (this) {
  528.         Graphics gBoard = iBoard.getGraphics();
  529.         xoffset = 0;
  530.         yoffset = 0;
  531.         for (rank = 0 ; rank < 8 ; rank++) {
  532.             for (file = 0 ; file < 8 ; file++) {
  533.             if (squarecount == 0 || updateArray.value(file,rank) != 0 || timer != null) {
  534.               if (blackOnTop)  {
  535.                 newxoff = file*xoff;
  536.                 newyoff =  yoff*7 - (rank*yoff);
  537.               }
  538.               else {
  539.                 newxoff = xoff*7 -(file*xoff);
  540.                 newyoff = rank*yoff;
  541.               }
  542.               i = squareColor.value(file,rank) +
  543.                   colorarray.value(file,rank) +
  544.                   piecearray.value(file,rank);
  545.               gBoard.translate(newxoff - xoffset,newyoff-yoffset);
  546.               gBoard.drawImage(iPiece[i],0,0,this);
  547.               xoffset = newxoff;
  548.               yoffset = newyoff;
  549.         }
  550.           }
  551.         }
  552.         gBoard.dispose();
  553.       }
  554.  
  555.       if (timer != null) {
  556.         synchronized(timer) {
  557.           if (badTimeToStopThread)
  558.             System.out.println("How can it stop now?");
  559.           animate = false;
  560.           timer.notify();
  561.          timer = null;
  562.         }
  563.       }
  564.       repaint();
  565.     }
  566.     }
  567.     prevpos.init(piecearray);
  568.     pieceColor.init(colorarray);
  569.   }
  570.  
  571.   public void stop() {
  572.     if (timer != null)
  573.       timer.stop();
  574.     System.out.println("Chessboard.stop was called");
  575.     timer = null;
  576.   }
  577.  
  578.   //java.awt.Runnable method
  579.   public void run() {
  580.     int i;
  581.     int myy;
  582.     int myx;
  583.     animate = true;
  584.     Graphics gBoard = iBoard.getGraphics();
  585.     Graphics gAnimationBackground  = iAnimationBackground.getGraphics();
  586.  
  587.     try {
  588.       if (isLive = isEnabled())
  589.         setEnabled(false); //so stray mouse clicks don't screw us over
  590.       int  absx = xincrement;
  591.       int absy = yincrement;
  592.       if (absx < 0)
  593.           absx = -absx;
  594.       if (absy < 0)
  595.           absy = -absy;
  596.       absx = absx + absy;
  597.       int timedelay = 10;
  598.       if (absx > 2)
  599.           timedelay = 15;
  600.       myx = xoffset;
  601.       myy = yoffset;
  602.       gBoard.translate(xoffset,yoffset);
  603.       int endingXOffset = xoffset + offset[1]*xincrement/2;
  604.       int endingYOffset = yoffset + offset[1]*yincrement/2;
  605.  
  606.       boolean skip = false;
  607.       int loopcount = offset[1] /2;
  608.       if (p > finalPiece)
  609.         p = finalPiece;  //promoted pieces moving backwards move as pawns
  610.       int endingpiece = finalPiece + squareColor.value(pointbx,pointby) ;
  611.       int piece = p;
  612.       for (i=0;i<loopcount;i++) {
  613.         if (iPiecemask[p] == null)
  614.           System.out.println("Chessboard.run iPiecemask[" + p + "] null ");
  615.         int translatex;
  616.         int translatey;
  617.         synchronized (this) {
  618.           if (animate) {
  619.             badTimeToStopThread = true;
  620.             translatex = myx - xoffset ;
  621.             translatey = myy - yoffset ;
  622.             if (translatex + translatey != 0) {
  623.               gBoard.translate(translatex,translatey);
  624.               xoffset = xoffset + translatex;
  625.               yoffset = yoffset + translatey;
  626.             }
  627.             myx = xoffset + xincrement;
  628.             myy = yoffset + yincrement;
  629.               gBoard.drawImage(iAnimationBackground,0,0,this);
  630.             gAnimationBackground.drawImage(iBoard,-1*myx,-1*myy,this);
  631.             translatex = myx-xoffset;
  632.             translatey = myy-yoffset;
  633.             gBoard.translate(translatex,translatey);
  634.             xoffset = myx;
  635.             yoffset = myy;
  636.             gBoard.drawImage(iPiecemask[piece],0,0,this);
  637.             badTimeToStopThread = false;
  638.           }
  639.           else
  640.             break;
  641.         }
  642.         if ( skip == false) {
  643.           repaint();
  644.           try {Thread.sleep(timedelay);}
  645.           catch (InterruptedException e){}
  646.           catch (Exception e){System.err.println("Chessbord.run "+ e.toString());}
  647.         }
  648.         if (timedelay ==  10)
  649.           if (skip == false)
  650.             skip = true;
  651.           else
  652.             skip = false;
  653.       }
  654.       if (animate) {
  655.         synchronized (this) {
  656.           int translatex = myx - xoffset ;
  657.           int translatey = myy - yoffset ;
  658.           if (translatex + translatey != 0) {
  659.             xoffset = xoffset + translatex;
  660.             yoffset = yoffset + translatey;
  661.             gBoard.translate(translatex,translatey);
  662.           }
  663.           gBoard.drawImage(iAnimationBackground,0,0,this);
  664.           gBoard.translate(endingXOffset - xoffset,endingYOffset - yoffset);
  665.           xoffset = endingXOffset;
  666.           yoffset = endingYOffset;
  667.           gBoard.drawImage(iPiece[endingpiece],0,0,this);
  668.         }
  669.       }
  670.       if (isLive)
  671.         setEnabled(true);
  672.     }
  673.     catch(Exception x ) {System.err.println("Chessboard.run "+ x.toString());}
  674.     catch(ThreadDeath x) {
  675.       if (badTimeToStopThread)
  676.         System.out.println("You picked the wrong time to give up running");
  677.       else
  678.         System.err.println("ThreadDeath");
  679.       if (isLive)
  680.         setEnabled(true);
  681.       throw x;
  682.     }
  683.     gBoard.dispose();
  684.     gAnimationBackground.dispose();
  685.     xoffset = 0;
  686.     yoffset = 0;
  687.     repaint();
  688.     timer = null;
  689.   }
  690.  
  691.   //java.awt.Component method
  692.   public void update(Graphics g) {
  693.     paint(g);
  694.   }
  695.  
  696.   //java.awt.Component method
  697.   public void paint(Graphics g) {
  698.     //System.err.println("Chessboard.paint " + init + " initfailed=" + initfailed);
  699.     if (init == true && initfailed == false) {
  700.       if (blackOnTop ^ blackGoesOnTop) {
  701.         drawBorder();
  702.       }
  703.       g.drawImage(iBoard,0,0,this);
  704.     }
  705.     else {
  706.       g.setColor(getBackground());
  707.       g.fillRect(0,0,280,280);
  708.       g.setColor(Color.blue );
  709.       g.drawString(initstring,10,135);
  710.       //The designers first call to setImage never seems to work
  711.       if (retryImage && init == false && initfailed == false && boardURL != null)
  712.         setImageURL(boardURL);
  713.     }
  714.   }
  715.  
  716.   // java.awt.MouseMotionListener method
  717.   public void mouseDragged(MouseEvent mev)  {
  718.     if (mouseActive == true) {
  719.       currentTime = System.currentTimeMillis();
  720.       int squareRadius = offset[1]/2;  //fudge factor so image is centered on the cursor
  721.       int x = mev.getX() - squareRadius;
  722.       int y = mev.getY() - squareRadius;
  723.       //System.out.println("mouse dragged");
  724.       synchronized (this) {
  725.         Graphics gBoard = iBoard.getGraphics();
  726.         gBoard.translate(xOldMouse,yOldMouse);
  727.         gBoard.drawImage(iBackground,0,0,this);
  728.         gBoard.translate(x-xOldMouse,y-yOldMouse);
  729.         xOldMouse = x;
  730.         yOldMouse = y;
  731.         Graphics gBackground = iBackground.getGraphics();
  732.         gBackground.drawImage(iBoard,-1*(xOldMouse),-1*(yOldMouse),this);
  733.         gBoard.drawImage(iPiecemask[p],0,0,this);
  734.         gBoard.dispose();
  735.         gBackground.dispose();
  736.       }
  737.       repaint();
  738.     }
  739.     return ;
  740.   }
  741.  
  742.   // java.awt.MouseMotionListener method
  743.   public void mouseMoved(MouseEvent e){}
  744.  
  745.   // java.awt.MouseListener method
  746.   public void mouseClicked(MouseEvent e){}
  747.  
  748.   // java.awt.MouseListener method
  749.   public void mouseExited(MouseEvent e){}
  750.  
  751.   // java.awt.MouseListener method
  752.   public void mouseEntered(MouseEvent e){}
  753.  
  754.   // java.awt.MouseListener method
  755.   public void  mousePressed(MouseEvent mev)     {
  756.     int x = mev.getX();
  757.     int y = mev.getY();
  758.     int squareSize = offset[1] ;
  759.     //System.out.println("mouse pressed");
  760.     int mousex = (x / squareSize) * squareSize;
  761.     int mousey = (y / squareSize) * squareSize;
  762.     if (x/squareSize > 7 || y /squareSize > 7)  {
  763.       //System.out.println("click out of bounds" + squareSize + "," + x  + "," + y);
  764.       return ;
  765.     }
  766.     synchronized (this) {
  767.       xoffset = mousex ;
  768.       yoffset = mousey;
  769.       xOldMouse = xoffset;
  770.       yOldMouse = yoffset;
  771.       if (blackOnTop) {
  772.         startfile = x/squareSize;
  773.         startrank =  7 - (y/squareSize);
  774.       }
  775.       else {
  776.         startfile = 7 - (x/squareSize);
  777.         startrank = y/squareSize;
  778.       }
  779.       p = prevpos.value(startfile,startrank) ;
  780.       if (p > 0) {
  781.         p = p + pieceColor.value(startfile,startrank);
  782.         Graphics gBackground = iBackground.getGraphics();
  783.         gBackground.drawImage(iPiece[squareColor.value(startfile,startrank)],0,0,this);
  784.         gBackground.dispose();
  785.         mouseActive = true;
  786.       }
  787.     }
  788.     return ;
  789.   }
  790.  
  791.   // java.awt.MouseListener method
  792.   public void mouseReleased(MouseEvent mev){
  793.     if (!mouseActive)
  794.        return ;
  795.      //System.out.println("mouse released");
  796.     int x = mev.getX();
  797.     int y = mev.getY();
  798.     int piecevalue =0;
  799.     int piececolor =0;
  800.     synchronized (this) {
  801.       Graphics gBoard = iBoard.getGraphics();
  802.       if (mouseActive) {
  803.         gBoard.translate(xOldMouse,yOldMouse);
  804.         gBoard.drawImage(iBackground,0,0,this);
  805.       }
  806.       else {
  807.         xOldMouse = 0;
  808.         yOldMouse = 0;
  809.       }
  810.       int squareSize = offset[1] ;
  811.       int mousex = (x / squareSize) * squareSize;
  812.       int mousey = (y / squareSize) * squareSize;
  813.       if (blackOnTop) {
  814.         endfile = x/squareSize;
  815.         endrank =  7 - (y/squareSize);
  816.       }
  817.       else {
  818.         endfile = 7 - (x/squareSize);
  819.         endrank = y/squareSize;
  820.       }
  821.       if (startrank != endrank || startfile != endfile) {
  822.         if (endrank < 0 || endrank > 7 || endfile < 0 ||
  823.             endfile > 7) {
  824.           endrank = startrank;
  825.           endfile = startfile;
  826.           if (blackOnTop) {
  827.             mousex = startfile * squareSize;
  828.             mousey = (7 - startrank) * squareSize;
  829.           }
  830.           else {
  831.             mousex = (7 - startfile) * squareSize;
  832.             mousey = startrank * squareSize;
  833.           }
  834.         }
  835.         if (startrank < 0 || startrank > 7)
  836.            System.out.println("Startrank =" + startrank + "??");
  837.         if (startfile < 0 || startfile > 7)
  838.            System.out.println("Startfile =" + startfile + "??");
  839.  
  840.         piecevalue = prevpos.value(startfile,startrank);
  841.         piececolor = pieceColor.value(startfile,startrank);
  842.         prevpos.assign(startfile,startrank,0);
  843.         pieceColor.assign(startfile,startrank,0);
  844.         prevpos.assign(endfile,endrank,piecevalue);
  845.         pieceColor.assign(endfile,endrank,piececolor);
  846.       }
  847.       gBoard.translate(mousex - xOldMouse,mousey - yOldMouse);
  848.       int w =  squareColor.value(endfile,endrank) + p;
  849.       gBoard.drawImage(iPiece[w],0,0,this);
  850.       gBoard.dispose();
  851.     }
  852.     repaint();
  853.     if (startrank != endrank || startfile != endfile) {
  854.       broadcast(piecevalue,piececolor);
  855.     }
  856.     mouseActive = false;
  857.     return ;
  858.   }
  859.  
  860.   void broadcast(int piecevalue,int piececolor) {
  861.     boolean showPromotionDialog = false;
  862.     PromotionDialog dDialog = null;
  863.     try {
  864.       if (piecevalue == PAWN  &&
  865.          (endrank == 0 || endrank == 7)) {
  866.         if (piececolor == WHITEPIECE && startrank ==6) {
  867.           showPromotionDialog = true;
  868.           dDialog = new PromotionDialog(getFrame(this),promoteWhite,this);
  869.         }
  870.         else
  871.           if (piececolor == BLACKPIECE && startrank ==1) {
  872.             showPromotionDialog = true;
  873.             dDialog = new PromotionDialog(getFrame(this),promoteBlack,this);
  874.           }
  875.       }
  876.       if (showPromotionDialog){
  877.         //System.out.println("Show promotion dialog");
  878.         dDialog.pack();
  879.         dDialog.setLocation(360,300);
  880.         dDialog.show();
  881.         //System.out.println(" promotion dialog Shown");
  882.       }
  883.       else {
  884.         tuple = new MoveTuple();
  885.         tuple.pieceValue = prevpos.value(endfile,endrank);
  886.         tuple.newpieceValue = tuple.pieceValue;
  887.         tuple.pieceColor = pieceColor.value(endfile,endrank);
  888.         tuple.fromFile = startfile;
  889.         tuple.fromRank = startrank;
  890.         tuple.toFile = endfile;
  891.         tuple.toRank = endrank;
  892.         handleActionEvent(new ActionEvent(this,1,null));
  893.       }
  894.     }
  895.     catch (Exception e) {
  896.       e.printStackTrace();
  897.     }
  898.   }
  899.  
  900.   public static Frame getFrame(Component theComponent) {
  901.     Component currParent = theComponent;
  902.     Frame theFrame = null;
  903.     while (currParent != null)  {
  904.       if (currParent instanceof Frame){
  905.         theFrame = (Frame) currParent;
  906.         break;
  907.       }
  908.       currParent = currParent.getParent();
  909.     }
  910.     return theFrame;
  911.   }
  912.  
  913.   public synchronized void addActionListener(ActionListener l) {
  914.     if (listener == null)
  915.       listener = l;
  916.   }
  917.  
  918.   public synchronized void removeActionListener(ActionListener l) {
  919.     listener = null;
  920.   }
  921.  
  922.   public ActionListener getActionListener() {
  923.     return listener;
  924.   }
  925.  
  926.   protected  void handleActionEvent(ActionEvent ae) {
  927.     if (getActionListener() != null) {
  928.       getActionListener().actionPerformed(ae);
  929.     }
  930.   }
  931.  
  932.   public MoveTuple getTuple() {
  933.     return tuple;
  934.   }
  935.  
  936.   void promote(int piecesub) {
  937.     tuple = new MoveTuple();
  938.     switch (piecesub)    {
  939.       case 3:
  940.         tuple.newpieceValue = QUEEN;
  941.         break;
  942.       case 1:
  943.         tuple.newpieceValue = KNIGHT;
  944.         break;
  945.       case 0:
  946.         tuple.newpieceValue = ROOK;
  947.         break;
  948.       case 2:
  949.         tuple.newpieceValue = BISHOP;
  950.         break;
  951.     }
  952.     tuple.pieceValue = prevpos.value(endfile,endrank);
  953.     tuple.pieceColor = pieceColor.value(endfile,endrank);
  954.     tuple.fromFile = startfile;
  955.     tuple.fromRank = startrank;
  956.     tuple.toFile = endfile;
  957.     tuple.toRank = endrank;
  958.     handleActionEvent(new ActionEvent(this,1,null));
  959.   }
  960.  
  961.   public boolean isBlackOnTop() {
  962.     return blackOnTop;
  963.   }
  964.  
  965.   public boolean switchOrientation()  {
  966.     blackOnTop = !blackOnTop;
  967.     int squareSize = offset[1];
  968.     int rank,file,newxoff,newyoff,i;
  969.     int xoffset = 0;
  970.     int yoffset = 0;
  971.     Graphics gBoard = iBoard.getGraphics();
  972.     for (rank = 0 ; rank < 8 ; rank++) {
  973.       for (file = 0 ; file < 8 ; file++) {
  974.         if (blackOnTop) {
  975.           newxoff = file*squareSize;
  976.           newyoff =  squareSize*7 - (rank*squareSize);
  977.         }
  978.         else {
  979.           newxoff = squareSize*7 -(file*squareSize);
  980.           newyoff = rank*squareSize;
  981.         }
  982.         i = squareColor.value(file,rank) +
  983.             pieceColor.value(file,rank) +
  984.             prevpos.value(file,rank);
  985.         synchronized (this) {
  986.           gBoard.translate(newxoff - xoffset  ,newyoff-yoffset );
  987.           gBoard.drawImage(iPiece[i], 0, 0, this);
  988.           xoffset = newxoff;
  989.           yoffset = newyoff;
  990.         }
  991.       }
  992.     }
  993.     gBoard.dispose();
  994.     repaint();
  995.     return blackOnTop;
  996.   }
  997. }
  998.  
  999. class Transparent extends RGBImageFilter
  1000. {
  1001.   int BackgroundPixel = 0xFF00FF00;
  1002.   public Transparent() {
  1003.     canFilterIndexColorModel = false;
  1004.   }
  1005.  
  1006.   public int filterRGB(int x, int y,int rgb) {
  1007.     try{
  1008.       if (x == 0 && y ==0)
  1009.         BackgroundPixel = rgb;
  1010.       if (BackgroundPixel == rgb)
  1011.         rgb = rgb & 0x00FFFFFF  ;
  1012.     }
  1013.     catch(Exception e) {
  1014.       e.printStackTrace();
  1015.       //System.out.println("filterRGB "  + e.toString());
  1016.     }
  1017.     return rgb;
  1018.   }
  1019. }
  1020.  
  1021.  
  1022.